1 /**
2 Copyright: Copyright (c) 2018, Joakim Brännström. All rights reserved.
3 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
4 Author: Joakim Brännström (joakim.brannstrom@gmx.com)
5 */
6 module app;
7 
8 import std.algorithm : among;
9 import std.exception : collectException;
10 import std.typecons : Flag, Yes, No;
11 import logger = std.experimental.logger;
12 
13 import code_checker.cli : Config;
14 import code_checker.compile_db : CompileCommandDB;
15 import code_checker.types : AbsolutePath, Path, AbsoluteFileName;
16 
17 int main(string[] args) {
18     import std.functional : toDelegate;
19     import code_checker.cli : AppMode, parseCLI, parseConfigCLI, loadConfig,
20         Config;
21     import code_checker.logger;
22     import app_normal;
23 
24     auto conf = () {
25         auto conf = Config.make();
26         try {
27             confLogger(VerboseMode.info);
28             conf.miniConf = parseConfigCLI(args);
29             loadConfig(conf);
30         } catch (Exception e) {
31             logger.warning(e.msg);
32             logger.warning("Unable to read configuration");
33         }
34         return conf;
35     }();
36     parseCLI(args, conf);
37     confLogger(conf.logg.verbose);
38     logger.trace(conf);
39 
40     alias Command = int delegate(ref Config conf);
41     Command[AppMode] cmds;
42     cmds[AppMode.none] = toDelegate(&modeNone);
43     cmds[AppMode.help] = toDelegate(&modeNone);
44     cmds[AppMode.helpUnknownCommand] = toDelegate(&modeNone_Error);
45     cmds[AppMode.normal] = toDelegate(&modeNormal);
46     cmds[AppMode.initConfig] = toDelegate(&modeInitConfig);
47     cmds[AppMode.dumpConfig] = toDelegate(&modeDumpFullConfig);
48 
49     if (auto v = conf.mode in cmds) {
50         return (*v)(conf);
51     }
52 
53     logger.error("Unknown mode %s", conf.mode);
54     return 1;
55 }
56 
57 int modeNone(ref Config conf) {
58     return 0;
59 }
60 
61 int modeNone_Error(ref Config conf) {
62     return 1;
63 }
64 
65 int modeInitConfig(ref Config conf) {
66     import std.stdio : File;
67     import std.file : exists;
68 
69     if (exists(conf.miniConf.confFile)) {
70         logger.error("Configuration file already exists: ", conf.miniConf.confFile);
71         return 1;
72     }
73 
74     try {
75         File(conf.miniConf.confFile, "w").write(conf.toTOML(No.fullConfig));
76         logger.info("Wrote configuration to ", conf.miniConf.confFile);
77         return 0;
78     } catch (Exception e) {
79         logger.error(e.msg);
80     }
81 
82     return 1;
83 }
84 
85 int modeDumpFullConfig(ref Config conf) {
86     import std.stdio : writeln, stderr;
87 
88     // make it easy for a user to pipe the output to the confi file
89     stderr.writeln("Dumping the configuration used. The format is TOML (.toml)");
90     stderr.writeln("If you want to use it put it in your '.code_checker.toml'");
91 
92     writeln(conf.toTOML(Yes.fullConfig));
93 
94     return 0;
95 }